import os, shutil, random
from tqdm import tqdm
from os import sep

# 将标签为xml格式的数据集按照7:2:1的比例划分为训练集,验证集和测试集

IMG_FILE_EXTENSION = ".jpg"
LABEL_FILE_EXTENSION = ".txt"
DATA_DIRECTORY = "DataSet"


def split_img(img_path, label_path, split_list):
    if not os.path.exists(DATA_DIRECTORY):
        os.mkdir(DATA_DIRECTORY)

        train_img_dir = DATA_DIRECTORY + sep + "images" + sep + "train"
        val_img_dir = DATA_DIRECTORY + sep + "images" + sep + "val"
        test_img_dir = DATA_DIRECTORY + sep + "images" + sep + "test"

        train_label_dir = DATA_DIRECTORY + sep + "labels" + sep + "train"
        val_label_dir = DATA_DIRECTORY + sep + "labels" + sep + "val"
        test_label_dir = DATA_DIRECTORY + sep + "labels" + sep + "test"

        # 创建文件夹
        os.makedirs(train_img_dir)
        os.makedirs(train_label_dir)
        os.makedirs(val_img_dir)
        os.makedirs(val_label_dir)
        os.makedirs(test_img_dir)
        os.makedirs(test_label_dir)
    else:
        print("The file directory already exists")

    train, val, test = split_list
    all_img = os.listdir(img_path)
    all_img_path = [os.path.join(img_path, img) for img in all_img]
    train_img = random.sample(all_img_path, int(train * len(all_img_path)))
    train_label = [struct_label_path(img, label_path) for img in train_img]

    partition_and_copy(
        train_img,
        train_img_dir,
        train_label,
        train_label_dir,
        all_img_path,
        val_img_dir,
        val_label_dir,
        label_path,
        val,
        test,
        test_img_dir,
        test_label_dir,
    )


def partition_and_copy(
    train_img,
    train_img_dir,
    train_label,
    train_label_dir,
    all_img_path,
    val_img_dir,
    val_label_dir,
    label_path,
    val,
    test,
    test_img_dir,
    test_label_dir,
):
    desc_train = "train "
    desc_val = "val "
    desc_test = "test "
    unit_name = "img"
    column = 80

    for i in tqdm(range(len(train_img)), desc=desc_train, ncols=column, unit=unit_name):
        copy_method(train_img[i], train_img_dir)
        copy_method(train_label[i], train_label_dir)
        all_img_path.remove(train_img[i])

    val_img = random.sample(all_img_path, int(val / (val + test) * len(all_img_path)))
    val_label = [struct_label_path(img, label_path) for img in val_img]

    for i in tqdm(range(len(val_img)), desc=desc_val, ncols=column, unit=unit_name):
        copy_method(val_img[i], val_img_dir)
        copy_method(val_label[i], val_label_dir)
        all_img_path.remove(val_img[i])

    test_img = all_img_path
    test_label = [struct_label_path(img, label_path) for img in test_img]

    for i in tqdm(range(len(test_img)), desc=desc_test, ncols=column, unit=unit_name):
        copy_method(test_img[i], test_img_dir)
        copy_method(test_label[i], test_label_dir)


def copy_method(from_path, to_path):
    shutil.copy(from_path, to_path)


def struct_label_path(img_path, label_path):
    img = img_path.split(sep)[-1]
    # 因为数据集标签是xml格式,所以是xml;如果标签格式是txt格式,就改成txt
    label = img.split(IMG_FILE_EXTENSION)[0] + LABEL_FILE_EXTENSION
    return os.path.join(label_path, label)


def main():
    img_path = r"C:\Users\user\Downloads\666"
    label_path = r"C:\Users\user\Downloads\labels"
    split_list = [0.7, 0.2, 0.1]  # 数据集划分比例[train:val:test]
    split_img(img_path, label_path, split_list)


if __name__ == "__main__":
    main()
